package com.liu.spring.framework.apo;

import com.liu.spring.framework.apo.intercept.MethodInvocation;
import com.liu.spring.framework.apo.suppport.AdvisedSupport;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

/**
 * @author LIU
 * @version 1.0
 * @date 2024/5/18 16:59
 * @description TODO
 */
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler {

    private AdvisedSupport advised;

    public JdkDynamicAopProxy(AdvisedSupport advised) {
        this.advised = advised;
    }


    /**
     * 拦截方法
     * 责任链方法
     * @param proxy 代理类
     * @param method 方法
     * @param args  入参
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 方法调用链
        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, this.advised.getTargetClass());

        //
        MethodInvocation mi = new MethodInvocation(proxy, this.advised.getTarget(), method, args, this.advised.getTargetClass(), chain);

        return mi.proceed();
    }

    @Override
    public Object getProxy() {
        return getProxy(this.getClass().getClassLoader());
    }


    @Override
    public Object getProxy(ClassLoader classLoader) {
        return Proxy.newProxyInstance(
                classLoader,
                this.advised.getTargetClass().getInterfaces(),
                this);
    }

}
